package spass.geometry;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.math.geometry.Vector3D;

public class Vector extends Point {

    public Vector(double x, double y, double z) {
        super(x, y, z);
    }

    public Vector scalarMultiply(double scalar) {
        Vector3D vector3d = toVector3D(this);
        Vector3D scaled = vector3d.scalarMultiply(scalar);

        return fromVector3D(scaled);
    }

    public double angleBetween(Vector other) {
        Vector3D this3d = toVector3D(this);
        Vector3D that3d = toVector3D(other);

        return Vector3D.angle(this3d, that3d);
    }

    public Vector toUnitVector() {
        Vector3D vector3d = toVector3D(this);
        Vector3D normalized = vector3d.normalize();

        return fromVector3D(normalized);
    }

    public Vector negate() {
        return new Vector(-getX(), -getY(), -getZ());
    }

    public double length() {
        return toVector3D(this).getNorm();
    }

    @Override
    public Vector copy() {
        return new Vector(getX(), getY(), getZ());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Vector) {
            Vector that = (Vector) obj;

            return new EqualsBuilder().append(this.getX(), that.getX()).append(this.getY(), that.getY())
                    .append(this.getZ(), that.getZ()).isEquals();
        }

        return false;
    }

    private Vector fromVector3D(Vector3D vector3d) {
        return new Vector(vector3d.getX(), vector3d.getY(), vector3d.getZ());
    }

    private Vector3D toVector3D(Vector vector) {
        return new Vector3D(vector.getX(), vector.getY(), vector.getZ());
    }
}
